package org.jparrow.framework.helper;

import java.lang.reflect.Field;
import java.util.Map;

import org.jparrow.framework.annotation.Inject;
import org.jparrow.framework.util.ArrayUtil;
import org.jparrow.framework.util.CollectionUtil;
import org.jparrow.framework.util.ReflectionUtil;

/**
 * 
 * 依赖注入助手类
 * 
 * DI
 * 通过BeanHelper获取出所有的Bean Map结构，记录了类与对象的映射关系
 * 然后遍历这个映射关系，取出Bean与Bean的实例，进而通过反射获取类中所有的成员
 * 变量。遍历这些成员变量，在循环中判断当前成员变量是否带有Inject注解，
 * 若带有该注解，则从BeanMap中根据Bean类取出Bean实例，最后通过ReflectionUtil
 * #setfield方法来修改当前成员变量的值
 * 
 * 注意：IOC容器生产的bean实例都是单例
 * 
 * @author supda
 * @date 2017-3-25
 * 
 */
public class IOCHelper {

	static {
		//获取所有的Bean类与Bean实例之间的映射关系(简称Bean Map)
		Map<Class<?>, Object> beanMap = BeanHelper.getBeanMap();
		if(CollectionUtil.isNotEmpty(beanMap)){
			//遍历BeanMap
			for(Map.Entry<Class<?>, Object> beanEntry : beanMap.entrySet()) {
				//从BeanMap 中获取Bean类与Bean实例
				Class<?> beanClass = beanEntry.getKey();
				Object beanInstance = beanEntry.getValue();
				
				//获取Bean类定义的所有成员变量（简称Bean Field）
				Field[] beanFields = beanClass.getDeclaredFields();
				if(ArrayUtil.isNotEmpty(beanFields)) {
					//遍历Bean Field
					for(Field beanField : beanFields) {
						//判断当前bean field 是否带有Inject注解
						if(beanField.isAnnotationPresent(Inject.class)){
							//在Bean Map中获取Bean Field对应的实例
							Class<?> beanFieldClass = beanField.getType();
							Object beanFieldInstance = beanMap.get(beanFieldClass);
							System.out.println("在Bean Map中获取Bean Field对应的实例,bean:"+beanFieldClass);
							if(beanFieldInstance != null) {
								//通过反射初始BeanField的值
								ReflectionUtil.setField(beanInstance, beanField, beanFieldInstance);
							}
						}
					}
				}
			}
		}
		System.out.println("IOC beanMap:"+beanMap);
	}
	
}
